*Write a permanent log file;
PROC PRINTTO LOG="C:\Research\Alcohol and Morbidity\7. Code Archive\Data Files and Code That Produced Them\P04 Inpatient Code up Visits.log" NEW;
RUN;

*Write a permanent list file;
PROC PRINTTO PRINT="C:\Research\Alcohol and Morbidity\7. Code Archive\Data Files and Code That Produced Them\P04 Inpatient Code up Visits.lst" NEW;
RUN;

/*
This program imports the California (2004-2007), Iowa (2004-2009) and Wisconsin (2004-2009) files and creates a month level counts
file. In the fourth quarter of 2007 in Wisconsin the source of admission is missing

California about 7% of ages are not calculable because they are suppressed. Gender is often suppressed also.
*/

*Libnames for Inpatient data;

libname CA_INP "D:\Data\Hospital Inpatient Records\Hospital California HCUP (2003-2010)";
libname IA_INP "D:\Data\Hospital Inpatient Records\Hospital Iowa (2004-2009)";
libname WI_INP "D:\Data\Hospital Inpatient Records\Hospital Wisconsin (2004-2010)";

*Variables to keep;
%let keep_v1 = bmonth byear amonth ayear ECODE1 DX1 FEMALE DISPUNIFORM PAY1  pay1;

%macro pull_s(lib,file,keep_v2,keep_v3,keep_v4,keep_v5,dx_max);
data &file. (drop = dx2-dx&dx_max.);
   format state $2.;
   set &lib..&file. (keep = &keep_v1. &keep_v2. &keep_v3. &keep_v4. &keep_v5. dx2-dx&dx_max.);
  *Record the file name and state postal code;
   file = "&file.";
   state = substr("&lib.",1,2);
  *Code up file source;
   if substr("&lib.",4,2) = 'IN' then inpatient = 1; else inpatient = 0; 
   *Compute age in months relative to age 21 - the intck function counts the number of starting 
   points of the interval crossed. So an ED visit occurring in the birth month will be 
   have a months_21 value of 0;
   months_21 = intck('month',mdy(bmonth,14,byear+21),mdy(amonth,15,ayear));
   if months_21 = . then bad_date = 1; else bad_date = 0;
  *Flag for ED admission on inpatient in some states they switch from one source coding to 
   another in 2007. In 2007 the rates dip in those states suggesting a slippage in coding is occurring;
   if inpatient = 1 and (&keep_v2. = "1" or &keep_v3. = "7") then from_ED = 1; else from_ED = 0;
  *Loop over ICD looking for alcohol mention start with second ICD code;
   array icd{&dx_max.} DX1-DX&dx_max.;
   alcohol_mention = 0;
   alcohol_mention_oth = 0;
   i = 2; *Start with second ICD code;
   do until (i > &dx_max.);
      if substr(icd{i},1,3) in ('291','303') or substr(icd{i},1,4) = '3050' then alcohol_mention = 1; 
	 *These are other minor mentions of alcohol;
      if substr(icd{i},1,4) in ("3575", "4255", "5353", "5710", "5711", "5712", "5713", "7903", "9800", "V113", "V791" )  then alcohol_mention_oth = 1; 
      if icd{i} = '' then i = 99; *Exit loop;
		 i+ +1;
   end;  
run;
*Very few records where other mention is 1 and alcohol mention is 0;
proc freq data = &file.;
   tables alcohol_mention*alcohol_mention_oth;
   title "For  &file.";
   where months_21 >= -36 and months_21 <= 36;
run;
%mend;

*Pull the inpatient records;
%pull_s(CA_INP,ca_sidc_2003_core,asource,byear,ECODE1-ECODE5,TOTCHG,25);
%pull_s(CA_INP,ca_sidc_2004_core,asource,byear,ECODE1-ECODE5,TOTCHG,25);
%pull_s(CA_INP,ca_sidc_2005_core,asource,byear,ECODE1-ECODE5,TOTCHG,25);
%pull_s(CA_INP,ca_sidc_2006_core,asource,byear,ECODE1-ECODE5,TOTCHG,25);
%pull_s(CA_INP,ca_sidc_2007_core,asource,byear,ECODE1-ECODE5,TOTCHG,25);
*%pull_s(CA_INP,ca_sidc_2008_core);*No birth year on this file;

%pull_s(IA_INP,ia_sidc_2004_core,asource,byear,ECODE1-ECODE6,TOTCHG,9);
%pull_s(IA_INP,ia_sidc_2005_core,asource,byear,ECODE1-ECODE6,TOTCHG,9);
%pull_s(IA_INP,ia_sidc_2006_core,asource,byear,ECODE1-ECODE6,TOTCHG,9);
%pull_s(IA_INP,ia_sidc_2007_core,asource,PointOfOriginUB04,ECODE1-ECODE8,TOTCHG,60);
%pull_s(IA_INP,ia_sidc_2008_core,byear,PointOfOriginUB04,ECODE1-ECODE7,TOTCHG,66);
%pull_s(IA_INP,ia_sidc_2009_core,byear,PointOfOriginUB04,ECODE1-ECODE12,TOTCHG,62);

%pull_s(WI_INP,wi_sidc_2004_core,asource,byear,ECODE1-ECODE5,TOTCHG,9);
%pull_s(WI_INP,wi_sidc_2005_core,asource,byear,ECODE1-ECODE5,TOTCHG,9);
%pull_s(WI_INP,wi_sidc_2006_core,asource,byear,ECODE1-ECODE7,TOTCHG,30);
%pull_s(WI_INP,wi_sidc_2007_core,asource,byear,ECODE1-ECODE12,TOTCHG,30);
%pull_s(WI_INP,wi_sidc_2008_core,byear,PointOfOriginUB04,ECODE1-ECODE9,TOTCHG,30);
%pull_s(WI_INP,wi_sidc_2009_core,byear,PointOfOriginUB04,ECODE1-ECODE10,TOTCHG,30); 
%pull_s(WI_INP,wi_sidc_2010_core,byear,PointOfOriginUB04,ECODE1-ECODE9,TOTCHG,30);  *NEW 6/4/2013;



*Combine the files;
data CA_IA_WI_inp;
   set 	ca_sidc_2003_core 	ca_sidc_2004_core  ca_sidc_2005_core  ca_sidc_2006_core  ca_sidc_2007_core
  							ia_sidc_2004_core  ia_sidc_2005_core  ia_sidc_2006_core  ia_sidc_2007_core  ia_sidc_2008_core  ia_sidc_2009_core 
  							wi_sidc_2004_core  wi_sidc_2005_core  wi_sidc_2006_core  wi_sidc_2007_core  wi_sidc_2008_core  wi_sidc_2009_core  wi_sidc_2010_core;
	format ad_date date.;
   *Drop bad dates there are 100,109 obs dropped for this reason and they are from all ages so the
	proportion of people with missing admission month which is creating the missing age is 100109/26711039 =  0.37 percent
	leaves 26,610,930 obs;
	if bad_date = 1 then delete;
   *Restrict to visits within 40 months of the month in which the birthday falls leaves 1,638,437
    admissions in this age range;
	if months_21 < -40 or months_21 > 39 then delete;
   *Remove inpatient stays that started before the time period we are examining leaves 1,635,860 obs;
    ad_date = mdy(amonth,15,ayear);
	if state in ('IA','WI') and ad_date < mdy(1,1,2004) then delete;
	if state = 'CA' and ad_date < mdy(1,1,2003) then delete;
   *Order Intoxication, injury (other, self, accident), mental illness and everything else is illness;
   *For this do both primary diagnosis (first diagnosis DX1 in all but a few states in time where they also have recoded visit reason)
	using visit reasons only adds a few percent more alcohol codes most times it is the same as DX1;
	alcohol = 0;
    if substr(DX1,1,3) in ('291','303') or substr(DX1,1,4) = '3050' then alcohol = 1; 
    if substr(DX_Visit_Reason1,1,3) in ('291','303') or substr(DX_Visit_Reason1,1,4) = '3050' then alcohol = 1; 
   *Overall injury category for regressions;
	if ECODE1 ne '' then injury = 1; else injury = 0;
   *Source and location of injury;
   array ECOD{12} ECODE1-ECODE12;
   inj_by_self_e = 0;
   inj_by_oth_e = 0;
   place = "       ";
  *Code up alcohol or drugs any mention;
   i = 1;
   do until (i > 12);
     *There are very few people that are coded as both (175) and going over all the ecodes only adds a few percent to the number coded; 
      if substr(ECOD{i},2,2) = '95' then inj_by_self_e = 1; 
      if substr(ECOD{i},2,2) = '96' then inj_by_oth_e = 1;  
	 *Place often coded for assaults;
      if substr(ECOD{i},2,3) = '849' then place = ECOD{i};
      if substr(ECOD{i},2,4) in ('8600','8601') then alcohol_mention_oth = 1; 
      if ECOD{i} = '' then i = 99; *Exit loop;
		 i+ +1;
   end;
  *Create mutually exclusive categories precedence - alcohol,;
    if alcohol = 0 and inj_by_oth_e = 1 then inj_by_oth  = 1; else inj_by_oth = 0;
    if alcohol = 0 and inj_by_oth_e = 0 and  inj_by_self_e = 1 then inj_by_self  = 1; else inj_by_self = 0;
    if alcohol = 0 and inj_by_oth_e = 0 and  inj_by_self_e = 0 and  injury = 1 then inj_accident  = 1; else inj_accident = 0;
    if alcohol = 0 and inj_by_oth_e = 0 and  inj_by_self_e = 0 and  injury = 0 and alcohol_mention = 1 then alcohol_on_dx = 1; else alcohol_on_dx = 0; *Alcohol not marked as primary cause but mentioned;
    if alcohol = 0 and inj_by_oth_e = 0 and  inj_by_self_e = 0 and  injury = 0 and alcohol_mention = 0 then illness = 1; else illness = 0; *Residual category;
  *Create combined categories;
   alcohol_any = alcohol + alcohol_on_dx;
   injury_or_alc =  inj_by_oth + inj_by_self + inj_accident + alcohol + alcohol_on_dx ;
  *Make sure the list is exhaustive;
	visit = alcohol + inj_by_self + inj_by_oth + inj_accident + alcohol_on_dx + illness;
  *Code up discharge; 
   if DISPUNIFORM = 20 then died = 1; else died = 0;
  *Flag for pregnant;
   preg_related = 0;
   if substr(DX1,1,2) in ('63','64','65','66','67') then preg_related = 1; 
   if substr(DX_Visit_Reason1,1,2) in ('63','64','65','66','67') then preg_related = 1; 
  *Flag for insurance;
   if pay1 = 2	then Medicaid = 1; else Medicaid = 0;
   if pay1 = 3	then Private = 1; else Private = 0;
   if pay1 = 4	then Self_pay = 1; else Self_pay = 0;
   if pay1 not in (2,3,4) then other_ins = 1; else other_ins = 0;
   file_short = substr(file,1,5);
   if TOTCHG = . then miss_chg = 1; else miss_chg = 0; 
   if female = . then miss_female = 1; else miss_female = 0; 
run;

*Clean up;
proc datasets;
   delete ia_sidc_2004_core  ia_sidc_2005_core  ia_sidc_2006_core  ia_sidc_2007_core  ia_sidc_2008_core  ia_sidc_2009_core 
          wi_sidc_2004_core  wi_sidc_2005_core  wi_sidc_2006_core  wi_sidc_2007_core  wi_sidc_2008_core  wi_sidc_2009_core wi_sidc_2010_core
          wisconsin_inp iowa_inp
          ca_sidc_2004_core  ca_sidc_2005_core  ca_sidc_2006_core  ca_sidc_2007_core;
run;

*Direct list file back to lst window;
PROC PRINTTO PRINT=PRINT;
RUN; 

*Direct log file back to log window;
PROC PRINTTO LOG=LOG;
RUN; 
